<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  <title>语音/文字上传（自动分段）</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      padding: 20px;
      background-color: #f5f5f5;
    }
    .container {
      max-width: 600px;
      margin: 0 auto;
      background: white;
      padding: 20px;
      border-radius: 8px;
      box-shadow: 0 2px 10px rgba(0,0,0,0.1);
    }
    h2 {
      text-align: center;
      color: #333;
    }
    textarea {
      width: 100%;
      height: 100px;
      padding: 10px;
      margin: 10px 0;
      border: 1px solid #ccc;
      border-radius: 4px;
      font-size: 16px;
      resize: vertical;
    }
    button {
      background-color: #007bff;
      color: white;
      padding: 10px 15px;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      font-size: 16px;
      margin-right: 10px;
    }
    button:disabled {
      background-color: #cccccc;
    }
    .status {
      margin-top: 10px;
      font-size: 14px;
      color: #666;
    }
    .listening {
      background-color: #28a745;
    }
    .recording {
      background-color: #dc3545;
    }
    .recording::after {
      content: ' ●';
      color: red;
      animation: blink 1.2s infinite;
    }
    @keyframes blink {
      0%, 100% { opacity: 1; }
      50% { opacity: 0.2; }
    }
  </style>
</head>
<body>
<div class="container">
  <h2>语音或文字上传（自动分段）</h2>

  <!-- 麦克风按钮 -->
  <button id="micBtn">🎤 开启监听</button>
  <span class="status" id="status">等待操作...</span>

  <!-- 文字输入框 -->
  <textarea id="textInput" placeholder="输入文字后按回车或点击发送"></textarea>
  <button id="sendTextBtn">📤 发送文字</button>
</div>

<script>
  const micBtn = document.getElementById('micBtn');
  const textInput = document.getElementById('textInput');
  const sendTextBtn = document.getElementById('sendTextBtn');
  const status = document.getElementById('status');

  let mediaStream = null;
  let audioContext = null;
  let analyser = null;
  let microphone = null;
  let mediaRecorder = null;
  let audioChunks = [];
  let isRecording = false;
  let silenceTimer = null;

  const SILENCE_THRESHOLD = -20;     // 分贝阈值（可调）
  const SILENCE_DURATION = 1500;     // 静音多久视为结束（毫秒）
  const CHECK_INTERVAL = 500;        // 检测频率

  // ========== 请求麦克风权限 ==========
  requestMicPermission();

  function requestMicPermission() {
    console.log('请求麦克风权限...');
    status.textContent = '正在请求麦克风权限...';
    navigator.mediaDevices.getUserMedia({ audio: true })
      .then(stream => {
        mediaStream = stream;
        setupAudioProcessing();
        status.textContent = '点击【开启监听】开始';
      })
      .catch(err => {
        status.textContent = `权限被拒绝: ${err.message}`;
        console.error('麦克风错误:', err);
      });
  }

  // ========== 设置音频分析环境 ==========
  function setupAudioProcessing() {
    console.log('设置音频分析环境...');
    audioContext = new (window.AudioContext || window.webkitAudioContext)();
    analyser = audioContext.createAnalyser();
    microphone = audioContext.createMediaStreamSource(mediaStream);
    microphone.connect(analyser);

    analyser.fftSize = 512;
    const bufferLength = analyser.frequencyBinCount;
    const dataArray = new Uint8Array(bufferLength);
    console.log('设置音频分析环境,前提变量已加载...');

    // ===== 创建 MediaRecorder（延迟创建）=====
    function createRecorder() {
      console.log('记录器创建开始...');
      mediaRecorder = new MediaRecorder(mediaStream);
      mediaRecorder.mimeType = 'audio/webm';

      mediaRecorder.ondataavailable = (event) => {
        console.log('记录器触发 ondataavailable...');
        if (event.data.size > 0 && isRecording) {
          const blob = new Blob([event.data], { type: 'audio/webm' });
          sendToBackend('audio', blob);
          isRecording = false;
          status.textContent = '已发送音频片段';
        }
      };

      mediaRecorder.onstop = () => {
        console.log('记录器触发 onstop...');
        stopSilenceDetection();
      };
    }

    // ===== 语音活动检测 loop =====
    function detectVoice() {
      console.log('语音活动检测 开始...');
      analyser.getByteFrequencyData(dataArray);
      const volume = dataArray.reduce((a, b) => a + b) / dataArray.length;

      // 转换为近似分贝值（简化）
      const dB = 20 * (Math.log(volume / 255) / Math.LN10);
      console.log('当前分贝:', dB);
      console.log('是否录音中:', isRecording);

      if (dB > SILENCE_THRESHOLD && !isRecording) {
        // 开始录音
        audioChunks = [];
        createRecorder();
        mediaRecorder.start();
        isRecording = true;
        status.textContent = '🎙 正在录音...';
        console.log('当前状态: 录音中');
        clearTimeout(silenceTimer);
      } else if (dB <= SILENCE_THRESHOLD && isRecording) {
        console.log('当前状态: 静音中');
        // 启动静音计时器
        if (!silenceTimer) {
          silenceTimer = setTimeout(() => {
            console.log('mediaRecorder: 自动停止');
            mediaRecorder.stop(); // 自动停止并触发 ondataavailable
          }, SILENCE_DURATION);
        }
      } else if (isRecording) {
        // 重置计时器
        clearTimeout(silenceTimer);
        silenceTimer = null;
      }

      // 继续检测
      if (micBtn.classList.contains('listening')) {
        setTimeout(() => {
          if (micBtn.classList.contains('listening')) {
            detectVoice();
          }
        }, CHECK_INTERVAL);
      }
    }

    function stopSilenceDetection() {
      console.log('stopSilenceDetection start...');
      if (silenceTimer) {
        console.log('stopSilenceDetection clear timer...');
        clearTimeout(silenceTimer);
        silenceTimer = null;
      }
      if (mediaRecorder && mediaRecorder.state === 'recording') {
        console.log('stopSilenceDetection mediaRecorder stop...');
        mediaRecorder.stop();
      }
      isRecording = false;
    }

    // ===== 麦克风开关逻辑 =====
    micBtn.addEventListener('click', () => {
      if (micBtn.classList.contains('listening')) {
        console.log('stop listening...');
        // 停止监听
        micBtn.textContent = '🎤 开启监听';
        micBtn.classList.remove('listening');
        stopSilenceDetection();
        status.textContent = '已停止监听';
      } else {
        console.log('start listening...');
        // 开始监听
        micBtn.textContent = '🛑 关闭监听';
        micBtn.classList.add('listening');
        status.textContent = '监听中...';
        detectVoice(); // 启动检测
      }
    });
  }

  // ========== 发送文字 ==========
  sendTextBtn.addEventListener('click', () => {
    const text = textInput.value.trim();
    if (text) {
      sendToBackend('text', text);
      textInput.value = '';
    } else {
      alert('请输入文字');
    }
  });

  textInput.addEventListener('keypress', (e) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      sendTextBtn.click();
    }
  });

  // ========== 统一发送到后端 ==========
  async function sendToBackend(type, data) {
    const formData = new FormData();
    formData.append('type', type);

    if (type === 'audio') {
      formData.append('file', data, 'chunk_' + Date.now() + '.webm');
    } else if (type === 'text') {
      formData.append('text', data);
    }

    try {
      const response = await fetch("/chat/audio", {  // ✅ 改为你的实际接口
        method: 'POST',
        body: formData
      });

      if (response.ok) {
        const result = await response.json();
        console.log('发送成功:', result);
        //你可以在这里处理 AI 回复，比如播放音频
        if (result.audio_url) {
          const audio = new Audio(result.audio_url);
          audio.play();
        }
      } else {
        throw new Error(`HTTP ${response.status}`);
      }
    } catch (error) {
      status.textContent = `发送失败: ${error.message}`;
      console.error('发送错误:', error);
    }
  }
</script>
</body>
</html>